luci-mod-dashboard: bug fixes and code cleanup
authorPaul Donald <[email protected]>
Sun, 7 Dec 2025 21:30:46 +0000 (22:30 +0100)
committerPaul Donald <[email protected]>
Sun, 7 Dec 2025 21:30:46 +0000 (22:30 +0100)
Signed-off-by: Paul Donald <[email protected]>
modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/css/custom.css
modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js
modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js

index f007c85638f90592cfee3d7f9a2e81add17cd837..73fadd179bf1557f6e92657cd2941ec402a1b0db 100644 (file)
 
 [data-darkmode="true"] {
        /* invert black SVG line drawings in dark mode */
-       .Dashboard
-       .svgmonotone {
+       .Dashboard .svgmonotone {
                filter: invert(.5);
        }
 }
index cb2d61db23bb616f3f7f52f3e8d2682670361eef..77fd57ead0a843af8b1b4ef575458bf3ac3faf45 100644 (file)
@@ -17,7 +17,6 @@ return baseclass.extend({
        load() {
                return Promise.all([
                        callLuciDHCPLeases(),
-                       network.getDevices()
                ]);
        },
 
@@ -36,7 +35,7 @@ return baseclass.extend({
                ]));
 
                const container_devices = E('table', { 'class': 'table assoclist devices-info' }, [
-                       E('tr', { 'class': 'tr dashboard-bg' }, [
+                       E('thead', { 'class': 'thead dashboard-bg' }, [
                                E('th', { 'class': 'th nowrap' }, _('Hostname')),
                                E('th', { 'class': 'th' }, _('IP Address')),
                                E('th', { 'class': 'th' }, _('MAC')),
@@ -46,7 +45,7 @@ return baseclass.extend({
                for(let idx in this.params.lan.devices) {
                        const device = this.params.lan.devices[idx];
 
-                       container_devices.appendChild(E('tr', { 'class': 'tr cbi-rowstyle-1'}, [
+                       container_devices.appendChild(E('tr', { 'class': idx % 2 ? 'tr cbi-rowstyle-2' : 'tr cbi-rowstyle-1' }, [
 
                                E('td', { 'class': 'td device-info'}, [
                                        E('p', {}, [
@@ -64,81 +63,58 @@ return baseclass.extend({
                                        E('p', {}, [
                                                E('span', { 'class': 'd-inline-block'}, [ device.macaddr ]),
                                        ]),
-                               ])
+                               ]),
                        ]));
                }
 
-               container_box.appendChild(container_devices);
-               container_wapper.appendChild(container_box);
+               container_devices.appendChild(E('tfoot', { 'class': 'tfoot dashboard-bg' }, [
+                       E('tr', { 'class': 'tr cbi-rowstyle-1' }, [
+                               E('td', { 'class': 'td device-info'}, [
+                                       E('p', {}, [
+                                               E('span', { 'class': 'd-inline-block'}, [ ]),
+                                       ]),
+                               ]),
 
-               return container_wapper;
-       },
+                               E('td', { 'class': 'td device-info'}, [
+                                       E('p', {}, [
+                                               E('span', { 'class': 'd-inline-block'}, [ _('Total') + ':' ]),
+                                       ]),
+                               ]),
 
-       renderUpdateData(data, leases) {
+                               E('td', { 'class': 'td device-info'}, [
+                                       E('p', {}, [
+                                               E('span', { 'class': 'd-inline-block'}, [ this.params.lan.devices.length ]),
+                                       ]),
+                               ]),
 
-               for(let item in data) {
-                       if (/lan|br-lan/ig.test(data[item].ifname) && (typeof data[item].dev == 'object' && !data[item].dev.wireless)) {
-                               const lan_device = data[item];
-                               const ipv4addr = lan_device.dev.ipaddrs.toString().split('/');
+                       ])
+               ]));
 
-                               this.params.lan.ipv4 = ipv4addr[0] || '?';
-                               this.params.lan.ipv6 = ipv4addr[0] || '?';
-                               this.params.lan.macaddr = lan_device.dev.macaddr || '00:00:00:00:00:00';
-                               this.params.lan.rx_bytes = lan_device.dev.stats.rx_bytes ? '%.2mB'.format(lan_device.dev.stats.rx_bytes)  : '-';
-                               this.params.lan.tx_bytes = lan_device.dev.stats.tx_bytes ? '%.2mB'.format(lan_device.dev.stats.tx_bytes)  : '-';
-                       }
-               }
+               container_box.appendChild(container_devices);
+               container_wapper.appendChild(container_box);
 
-               const devices = [];
-               leases.map(lease => {
-                       devices[lease.expires] = {
-                               hostname: lease.hostname || '?',
-                               ipv4: lease.ipaddr || '-',
-                               macaddr: lease.macaddr || '00:00:00:00:00:00',
-                       };
-               });
-               this.params.lan.devices = devices;
+               return container_wapper;
        },
 
-       renderLeases(data) {
-
-               const leases = Array.isArray(data[0].dhcp_leases) ? data[0].dhcp_leases : [];
-
-               this.params.lan = {
-                       ipv4: {
-                               title:  _('IPv4'),
-                               value: '?'
-                       },
-
-                       macaddr: {
-                               title: _('Mac'),
-                               value: '00:00:00:00:00:00'
-                       },
+       renderUpdateData(leases) {
+               const dev_arr = [];
 
-                       rx_bytes: {
-                               title: _('Upload'),
-                               value: '-'
-                       },
-
-                       tx_bytes: {
-                               title: _('Download'),
-                               value: '-'
-                       },
+               leases.forEach(({ hostname = '?', ipaddr: ipv4 = '-', macaddr = '00:00:00:00:00:00' }) => {
+                       dev_arr.push({ hostname, ipv4, macaddr });
+               });
 
-                       devices: {
-                               title: _('Devices'),
-                               value: []
-                       }
-               };
+               this.params.lan = { devices: dev_arr };
+       },
 
-               this.renderUpdateData(data[1], leases);
+       renderLeases(leases) {
+               this.renderUpdateData([...leases.dhcp_leases]);
 
                return this.renderHtml();
        },
 
-       render(data) {
+       render([leases]) {
                if (L.hasSystemFeature('dnsmasq') || L.hasSystemFeature('odhcpd'))
-                       return this.renderLeases(data);
+                       return this.renderLeases(leases);
 
                return E([]);
        }
index a31e6c958bd28acfd8652489cc03d8a72ebbbfee..03ef838d47284940f9600ecec8de73b710505d58 100644 (file)
@@ -34,7 +34,6 @@ return baseclass.extend({
                const container_wapper = E('div', { 'class': 'router-status-wifi dashboard-bg box-s1' });
                const container_box = E('div', { 'class': 'wifi-info devices-list' });
                const container_radio = E('div', { 'class': 'settings-info' });
-               let container_radio_item;
 
                container_box.appendChild(E('div', { 'class': 'title'}, [
                        E('img', {
@@ -48,7 +47,7 @@ return baseclass.extend({
 
                for (let i = 0; i < this.params.wifi.radios.length; i++) {
 
-                       container_radio_item = E('div', { 'class': 'radio-info' })
+                       const container_radio_item = E('div', { 'class': 'radio-info' })
 
                        for(let idx in this.params.wifi.radios[i]) {
                                let classname = idx;
@@ -77,16 +76,18 @@ return baseclass.extend({
                container_box.appendChild(container_radio);
 
                const container_devices = E('table', { 'class': 'table assoclist devices-info' }, [
+                       E('thead', { 'class': 'thead dashboard-bg' }, [
                        E('tr', { 'class': 'tr dashboard-bg' }, [
-                               E('th', { 'class': 'th nowrap' }, _('Hostname')),
-                               E('th', { 'class': 'th' }, _('SSID')),
-                               E('th', { 'class': 'th', 'width': '45%' }, _('Signal Strength')),
-                               E('th', { 'class': 'th' }, _('Transferred') + ' %s / %s'.format( _('Up.'), _('Down.')))
+                               E('th', { 'class': 'th nowrap' },[ _('Hostname') ]),
+                               E('th', { 'class': 'th' }, [ _('SSID') ]),
+                               E('th', { 'class': 'th', 'width': '45%' }, [ _('Signal Strength') ]),
+                               E('th', { 'class': 'th' }, [ _('Transferred') + ' %s / %s'.format( _('Up.'), _('Down.')) ])
+                       ])
                        ])
                ]);
 
                for (let i = 0; i < this.params.wifi.devices.length; i++) {
-                       const container_devices_item = E('tr', { 'class': 'tr cbi-rowstyle-1' });
+                       const container_devices_item = E('tr', { 'class': i % 2 ? 'tr cbi-rowstyle-2' : 'tr cbi-rowstyle-1' });
 
                        for(let idx in this.params.wifi.devices[i]) {
                                const device = this.params.wifi.devices[i];
@@ -95,36 +96,40 @@ return baseclass.extend({
                                        continue;
                                }
 
-                               let container_content;
-
                                if ('progress' == idx) {
-                                       container_content = E('td', { 'class' : 'td device-info' }, [
+                                       container_devices_item.appendChild(E('td', { 'class' : 'td device-info' }, [
                                                E('div', { 'class': 'cbi-progressbar', 'title': 'RSSI: ' + parseInt(device[idx].value.qualite) + '% (' + device[idx].value.rssi + 'dBm)'  }, [
                                                        E('div', { 'style': 'width: '+device[idx].value.qualite+'%'}),
                                                ])
-                                       ]);
+                                       ]));
                                } else if ('transferred' == idx) {
-                                       container_content = E('td', { 'class': 'td device-info'  }, [
+                                       container_devices_item.appendChild(E('td', { 'class': 'td device-info'  }, [
                                                E('p', {}, [
                                                        E('span', { 'class': ''}, [ device[idx].value.rx ]),
                                                        E('br'),
                                                        E('span', { 'class': ''}, [ device[idx].value.tx ])
                                                ])
-                                       ]);
+                                       ]));
                                } else {
-                                       container_content = E('td', { 'class': 'td device-info'}, [
+                                       container_devices_item.appendChild(E('td', { 'class': 'td device-info'}, [
                                                E('p', {}, [
                                                        E('span', { 'class': ''}, [ device[idx].value ]),
                                                ])
-                                       ]);
+                                       ]));
                                }
 
-                               container_devices_item.appendChild(container_content);
                        }
 
                        container_devices.appendChild(container_devices_item);
                }
 
+               container_devices.appendChild(E('tfoot', { 'class': 'tfoot dashboard-bg' }, [
+                               E('td', { 'class': 'td nowrap' }, [ ]),
+                               E('td', { 'class': 'td' }, [ _('Total') + ':' ]),
+                               E('td', { 'class': 'td' }, [ this.params.wifi.devices.length ]),
+                               E('td', { 'class': 'td' }, [] ),
+                       ]));
+
                container_box.appendChild(container_devices);
                container_wapper.appendChild(container_box);
 
@@ -249,14 +254,14 @@ return baseclass.extend({
                }
        },
 
-       render(data) {
+       render([radios, networks, hosthints]) {
 
                this.params.wifi = {
                        radios: [],
                        devices: []
                };
 
-               this.renderUpdateData(data[0], data[1], data[2]);
+               this.renderUpdateData(radios, networks, hosthints);
 
                if (this.params.wifi.radios.length)
                        return this.renderHtml();